#ifndef NV_USER_MEMALLOC_H

#define NV_USER_MEMALLOC_H

#include "NxSimpleTypes.h"
#include <assert.h>

#include <new>

#ifndef NULL
#define NULL 0
#endif

#define USE_MEMALLOC 1

#define NVSHARE nvshare

#pragma warning(push)
#pragma warning(disable:4100)

namespace NVSHARE
{

#define MEMALLOC_NEW(x) new(#x,__FILE__,__LINE__) x

inline void * inline_malloc(size_t size,const char *typeName,const char *fileName,int lineno)
{
  void *ret;
  ret = ::malloc(size);
  return ret;
}

inline void inline_free(void *mem,const char *fileName,int lineno)
{
	::free(mem);
}

inline void * inline_realloc(void *oldMem,size_t newSize,const char *typeName,const char *fileName,int lineno)
{
  void *ret;

	ret = ::realloc(oldMem,newSize);

	return ret;
}

#define MEMALLOC_MALLOC(x) NVSHARE::inline_malloc(x,"malloc",__FILE__,__LINE__)
#define MEMALLOC_MALLOC_TYPE(x,t,f,l) NVSHARE::inline_malloc(x,t,f,l)
#define MEMALLOC_FREE(x) NVSHARE::inline_free(x,__FILE__,__LINE__)
#define MEMALLOC_REALLOC(x,y) NVSHARE::inline_realloc(x,y,"malloc",__FILE__,__LINE__)

#pragma warning(push)
#pragma warning(disable:4100)


/**
Subclasses of this base class automatically take part in user memory management
Should be called Allocateable but then we collide with Ice::Allocateable.
*/
class Memalloc
{
public:
	NX_INLINE void* operator new(size_t size,Memalloc *t);
	NX_INLINE void* operator new(size_t size);
	NX_INLINE void* operator new[](size_t size);
	NX_INLINE void* operator new(size_t size,const char *className,const char* fileName, int line);
	NX_INLINE void* operator new[](size_t size,const char *className,const char* fileName, int line);

	NX_INLINE void  operator delete(void* p,Memalloc *t);
	NX_INLINE void  operator delete(void* p);
	NX_INLINE void  operator delete[](void* p);
	NX_INLINE void  operator delete(void *p,const char *className,const char* fileName, int line);
	NX_INLINE void  operator delete[](void *p,const char *className,const char* fileName, int line);
};

NX_INLINE void* Memalloc::operator new(size_t size,Memalloc *t)
{
	size;
	return t;
}


NX_INLINE void* Memalloc::operator new(size_t size)
{
	void *ret;

    ret = inline_malloc(size,"new",__FILE__,__LINE__);

    return ret;
}

NX_INLINE void* Memalloc::operator new[](size_t size)
{
	void *ret;

    ret  = inline_malloc(size,"new_array",__FILE__,__LINE__);

    return ret;
}

NX_INLINE void Memalloc::operator delete(void* p)
{
  	inline_free(p,__FILE__,__LINE__);
}

NX_INLINE void Memalloc::operator delete(void* p,Memalloc *)
{
    assert(0); // should never be executed.
}

NX_INLINE void Memalloc::operator delete[](void* p)
{
    inline_free(p,__FILE__,__LINE__);
}

NX_INLINE void Memalloc::operator delete(void* p,const char *className,const char *fileName,int lineno)
{
	inline_free(p,fileName,lineno);
}

NX_INLINE void Memalloc::operator delete[](void* p,const char *className,const char *fileName,int lineno)
{
	inline_free(p,fileName,lineno);
}

NX_INLINE void* Memalloc::operator new(size_t size,const char *className,const char* fileName, int lineno)
{
    void *ret;

	ret = inline_malloc(size,className,fileName,lineno);

    return ret;
}

NX_INLINE void* Memalloc::operator new[](size_t size,const char *className,const char* fileName, int lineno)
{
    void *ret;

    ret = inline_malloc(size,className,fileName,lineno);

	return ret;
}


}; // end of namespace

#define NV_MEMORY_BASE_CLASS NVSHARE::Memalloc

#pragma warning(pop)


#endif
